package com.jake.spring.boot.csv.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.springframework.http.HttpHeaders;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;

import static com.jake.spring.boot.csv.constant.CSVConstants.NEW_LINE_SEPARATOR;

@Slf4j
public class CSVUtils {

    public static File createTemp(List<String> heads, List<List<String>> records) {
        File file = null;
        BufferedWriter bufferedWriter = null;
        CSVPrinter printer = null;
        try {
            // 创建文件
            file = File.createTempFile("temp", ".csv");
            log.info("absolute path = {}, canonical path = {}", file.getAbsolutePath(), file.getCanonicalPath());
            CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR);
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
            printer = new CSVPrinter(bufferedWriter, format);
            // 写入表头
            printer.printRecord(heads);
            // 写入内容
            for (List<String> record : records) {
                printer.printRecord(record);
            }
        } catch (IOException e) {
            log.error("创建临时 CSV 文件时出错", e);
        } finally {
            try {
                if (printer != null) {
                    printer.close();
                }
                if (bufferedWriter != null) {
                    bufferedWriter.close();
                }
            } catch (IOException e) {
                log.error("创建临时 CSV 文件后关闭流时出错");
            }
        }
        return file;
    }

    public static void download(File file, String filename, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        try {
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename=" + new String(filename.getBytes("GB2312"),
                            StandardCharsets.ISO_8859_1) + ".csv");
        } catch (UnsupportedEncodingException e) {
            log.error("不支持的编码方式");
        }
        FileInputStream fileInputStream = null;
        BufferedInputStream bufferedInputStream = null;
        OutputStream os = null;
        try {
            fileInputStream = new FileInputStream(file);
            bufferedInputStream = new BufferedInputStream(fileInputStream);
            os = response.getOutputStream();
            // MS产本头部需要插入 BOM
            // 如果不写入这几个字节，会导致用 Excel 打开时，中文显示乱码
            os.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
            byte[] buffer = new byte[1024];
            int i = bufferedInputStream.read(buffer);
            while (i != -1) {
                os.write(buffer, 0, i);
                i = bufferedInputStream.read(buffer);
            }
        } catch (IOException e) {
            log.error("下载 CSV 文件时出错", e);
        } finally {
            // 关闭流
            try {
                if (os != null) {
                    os.flush();
                    os.close();
                }
                if (bufferedInputStream != null) {
                    bufferedInputStream.close();
                }
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
            } catch (IOException e) {
                log.error("下载结束关闭流时出错", e);
            } finally {
                file.delete();
            }
        }
    }
}
